1 package edu.jiangxin.apktoolbox.main;
2
3 import edu.jiangxin.apktoolbox.Version;
4 import edu.jiangxin.apktoolbox.android.dumpsys.DumpsysPanel;
5 import edu.jiangxin.apktoolbox.convert.base.BaseConvertPanel;
6 import edu.jiangxin.apktoolbox.convert.color.ColorConvertPanel;
7 import edu.jiangxin.apktoolbox.convert.color.ColorPickerPanel;
8 import edu.jiangxin.apktoolbox.convert.encoding.GarbledTextRecoveryPanel;
9 import edu.jiangxin.apktoolbox.convert.protobuf.supervised.SupervisedProtobufConvertPanel;
10 import edu.jiangxin.apktoolbox.convert.protobuf.unsupervised.UnsupervisedProtobufConvertPanel;
11 import edu.jiangxin.apktoolbox.convert.relationship.RelationShipConvertPanel;
12 import edu.jiangxin.apktoolbox.convert.time.TimeConvertPanel;
13 import edu.jiangxin.apktoolbox.convert.zh2unicode.Zh2UnicodeConvertPanel;
14 import edu.jiangxin.apktoolbox.file.batchrename.BatchRenamePanel;
15 import edu.jiangxin.apktoolbox.file.EncodeConvertPanel;
16 import edu.jiangxin.apktoolbox.file.OsConvertPanel;
17 import edu.jiangxin.apktoolbox.file.checksum.ChecksumPanel;
18 import edu.jiangxin.apktoolbox.file.password.recovery.RecoveryPanel;
19 import edu.jiangxin.apktoolbox.file.duplicate.DuplicateSearchPanel;
20 import edu.jiangxin.apktoolbox.file.zhconvert.ZhConvertPanel;
21 import edu.jiangxin.apktoolbox.help.*;
22 import edu.jiangxin.apktoolbox.android.i18n.I18nAddPanel;
23 import edu.jiangxin.apktoolbox.android.i18n.I18nFindLongestPanel;
24 import edu.jiangxin.apktoolbox.android.i18n.I18nRemovePanel;
25 import edu.jiangxin.apktoolbox.android.monkey.MonkeyPanel;
26 import edu.jiangxin.apktoolbox.help.settings.SettingsPanel;
27 import edu.jiangxin.apktoolbox.pdf.finder.PdfFinderPanel;
28 import edu.jiangxin.apktoolbox.pdf.passwordremover.PdfPasswordRemoverPanel;
29 import edu.jiangxin.apktoolbox.pdf.pic2pdf.Pic2PdfPanel;
30 import edu.jiangxin.apktoolbox.pdf.stat.PdfStatPanel;
31 import edu.jiangxin.apktoolbox.reverse.*;
32 import edu.jiangxin.apktoolbox.android.screenshot.ScreenShotPanel;
33 import edu.jiangxin.apktoolbox.reverse.ApktoolPanel;
34 import edu.jiangxin.apktoolbox.swing.extend.EasyFrame;
35 import edu.jiangxin.apktoolbox.swing.extend.EasyPanel;
36 import edu.jiangxin.apktoolbox.swing.extend.listener.ChangeMenuListener;
37 import edu.jiangxin.apktoolbox.swing.extend.listener.ChangeMenuToUrlListener;
38 import edu.jiangxin.apktoolbox.swing.extend.listener.IPreChangeMenuCallBack;
39 import edu.jiangxin.apktoolbox.swing.extend.plugin.ChangeMenuPreparePluginController;
40 import edu.jiangxin.apktoolbox.swing.extend.plugin.PluginPanel;
41 import edu.jiangxin.apktoolbox.swing.keeper.UiStateKeeper;
42 import edu.jiangxin.apktoolbox.utils.Utils;
43 import org.apache.commons.configuration2.Configuration;
44 import org.apache.commons.lang3.StringUtils;
45 import org.apache.logging.log4j.LogManager;
46 import org.apache.logging.log4j.Logger;
47
48 import javax.swing.*;
49 import javax.swing.border.EmptyBorder;
50 import java.awt.*;
51 import java.awt.event.*;
52 import java.io.Serial;
53 import java.lang.reflect.InvocationTargetException;
54 import java.text.MessageFormat;
55 import java.util.Locale;
56 import java.util.Objects;
57
58
59
60
61
62 public final class MainFrame extends EasyFrame {
63
64 @Serial
65 private static final long serialVersionUID = 1L;
66
67 private JPanel contentPane;
68 private EasyPanel currentEasyPanel = null;
69 private JMenuBar menuBar;
70
71 public static void main(String[] args) {
72 final Logger logger = LogManager.getLogger(MainFrame.class.getSimpleName());
73 boolean isEnvironmentOk = Utils.checkAndInitEnvironment();
74 if (!isEnvironmentOk) {
75 logger.error("Environment is not ready, exit");
76 return;
77 }
78 EventQueue.invokeLater(() -> {
79 Configuration conf = Utils.getConfiguration();
80 String lookAndFeelClassName = conf.getString("look.and.feel.class.name");
81 if (StringUtils.isEmpty(lookAndFeelClassName)) {
82 lookAndFeelClassName = "com.formdev.flatlaf.FlatDarculaLaf";
83 conf.setProperty("look.and.feel.class.name", lookAndFeelClassName);
84 }
85 try {
86 UIManager.setLookAndFeel(lookAndFeelClassName);
87 } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
88 logger.error("setLookAndFeel failed, use default instead", e);
89 }
90
91 String currentLocaleLanguage = conf.getString("locale.language");
92 if (StringUtils.isEmpty(currentLocaleLanguage)) {
93 currentLocaleLanguage = Locale.ENGLISH.getLanguage();
94 conf.setProperty("locale.language", currentLocaleLanguage);
95 }
96 Locale.setDefault(Locale.forLanguageTag(currentLocaleLanguage));
97
98 MainFrame frame = new MainFrame();
99
100 boolean isAlwaysOnTop = conf.getBoolean("always.on.top", false);
101 conf.setProperty("always.on.top", isAlwaysOnTop);
102 frame.setAlwaysOnTop(isAlwaysOnTop);
103
104 frame.setVisible(true);
105 });
106 }
107
108 public MainFrame() {
109 super();
110 initialize();
111 if (SystemTray.isSupported()) {
112 configSystemTray();
113 }
114
115 setTitle(MessageFormat.format(bundle.getString("main.title"), Version.VERSION));
116 setDefaultCloseOperation(EXIT_ON_CLOSE);
117 setMenuBar();
118 contentPane = new JPanel();
119 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
120 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
121 contentPane.add(Box.createVerticalGlue());
122 EasyPanel initPanel = new AboutPanel();
123 initPanel.init();
124 initPanel.setBorder(BorderFactory.createTitledBorder(bundle.getString("help.about.title")));
125 contentPane.add(initPanel);
126 contentPane.add(Box.createVerticalGlue());
127 setContentPane(contentPane);
128 refreshSizeAndLocation();
129 }
130
131 private void configSystemTray() {
132 SystemTray systemTray = SystemTray.getSystemTray();
133 PopupMenu popupMenu = new PopupMenu();
134 final MenuItem show = new MenuItem("Open");
135 final MenuItem exit = new MenuItem("Close");
136 ActionListener actionListener = e -> {
137 if (e.getSource() == show) {
138 setExtendedState(NORMAL);
139 setVisible(true);
140 }
141 if (e.getSource() == exit) {
142 dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
143 }
144 };
145 exit.addActionListener(actionListener);
146 show.addActionListener(actionListener);
147 popupMenu.add(show);
148 popupMenu.add(exit);
149 TrayIcon trayIcon = new TrayIcon(image, "系统托盘", popupMenu);
150 trayIcon.setImageAutoSize(true);
151 try {
152 systemTray.add(trayIcon);
153 } catch (AWTException e) {
154 logger.error("add icon to tray failed");
155 }
156 trayIcon.addMouseListener(new MouseAdapter() {
157 @Override
158 public void mouseClicked(MouseEvent e) {
159 if (e.getClickCount() == 2) {
160 setExtendedState(NORMAL);
161 setVisible(true);
162 }
163 }
164 });
165 }
166
167 private void setMenuBar() {
168 menuBar = new JMenuBar();
169 setJMenuBar(menuBar);
170
171 createReverseMenu();
172
173 createAndroidMenu();
174
175 createPdfMenu();
176
177 createFileMenu();
178
179 createConvertMenu();
180
181 createHelpMenu();
182 }
183
184 private void createHelpMenu() {
185 JMenu helpMenu = new JMenu(bundle.getString("help.title"));
186 menuBar.add(helpMenu);
187
188 JMenuItem documentMenuItem = new JMenuItem(bundle.getString("help.document.title"));
189 documentMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_DOCUMENT));
190 helpMenu.add(documentMenuItem);
191
192 JMenuItem settingsMenuItem = new JMenuItem(bundle.getString("help.settings.title"));
193 settingsMenuItem.addActionListener(new ChangeMenuToPanelListener(SettingsPanel.class, settingsMenuItem.getText()));
194 helpMenu.add(settingsMenuItem);
195
196 JMenuItem feedbackMenuItem = new JMenuItem(bundle.getString("help.feedback.title"));
197 feedbackMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_FEEDBACK));
198 helpMenu.add(feedbackMenuItem);
199
200 JMenuItem checkUpdateMenuItem = new JMenuItem(bundle.getString("help.checkupdate.title"));
201 checkUpdateMenuItem.addActionListener(new CheckUpdateActionListener(this));
202 helpMenu.add(checkUpdateMenuItem);
203
204 JMenuItem contributeMenuItem = new JMenuItem(bundle.getString("help.contribute.title"));
205 contributeMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_CONTRIBUTE));
206 helpMenu.add(contributeMenuItem);
207
208 JMenuItem aboutMenuItem = new JMenuItem(bundle.getString("help.about.title"));
209 aboutMenuItem.addActionListener(new ChangeMenuToPanelListener(AboutPanel.class, aboutMenuItem.getText()));
210 helpMenu.add(aboutMenuItem);
211 }
212
213 private void createPdfMenu() {
214 JMenu pdfMenu = new JMenu(bundle.getString("pdf.title"));
215 menuBar.add(pdfMenu);
216
217 JMenuItem pdfStatMenuItem = new JMenuItem(bundle.getString("pdf.stat.title"));
218 pdfStatMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfStatPanel.class, pdfStatMenuItem.getText()));
219 pdfMenu.add(pdfStatMenuItem);
220
221 JMenuItem pdfFinderMenuItem = new JMenuItem(bundle.getString("pdf.finder.title"));
222 pdfFinderMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfFinderPanel.class, pdfFinderMenuItem.getText()));
223 pdfMenu.add(pdfFinderMenuItem);
224
225 JMenuItem pdfPasswordRemoverMenuItem = new JMenuItem(bundle.getString("pdf.password.remover.title"));
226 pdfPasswordRemoverMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfPasswordRemoverPanel.class, pdfPasswordRemoverMenuItem.getText()));
227 pdfMenu.add(pdfPasswordRemoverMenuItem);
228
229 JMenuItem pic2PdfMenuItem = new JMenuItem(bundle.getString("pictures.to.pdf.title"));
230 pic2PdfMenuItem.addActionListener(new ChangeMenuToPanelListener(Pic2PdfPanel.class, pic2PdfMenuItem.getText()));
231 pdfMenu.add(pic2PdfMenuItem);
232 }
233
234 private void createFileMenu() {
235 JMenu fileMenu = new JMenu(bundle.getString("file.title"));
236 menuBar.add(fileMenu);
237
238 JMenuItem osConvertMenuItem = new JMenuItem(bundle.getString("file.os.convert.title"));
239 osConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(OsConvertPanel.class, osConvertMenuItem.getText()));
240 fileMenu.add(osConvertMenuItem);
241
242 JMenuItem encodeConvertMenuItem = new JMenuItem(bundle.getString("file.encode.convert.title"));
243 encodeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(EncodeConvertPanel.class, encodeConvertMenuItem.getText()));
244 fileMenu.add(encodeConvertMenuItem);
245
246 JMenuItem zhConvertMenuItem = new JMenuItem(bundle.getString("file.zh.convert.title"));
247 zhConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(ZhConvertPanel.class, zhConvertMenuItem.getText()));
248 fileMenu.add(zhConvertMenuItem);
249
250 JMenuItem duplicateFindMenuItem = new JMenuItem(bundle.getString("file.duplicate.title"));
251 duplicateFindMenuItem.addActionListener(new ChangeMenuToPanelListener(DuplicateSearchPanel.class, duplicateFindMenuItem.getText()));
252 fileMenu.add(duplicateFindMenuItem);
253
254 JMenuItem batchRenameMenuItem = new JMenuItem(bundle.getString("file.batch.rename.title"));
255 batchRenameMenuItem.addActionListener(new ChangeMenuToPanelListener(BatchRenamePanel.class, batchRenameMenuItem.getText()));
256 fileMenu.add(batchRenameMenuItem);
257
258 JMenuItem checkSumMenuItem = new JMenuItem(bundle.getString("file.check.summary.title"));
259 checkSumMenuItem.addActionListener(new ChangeMenuToPanelListener(ChecksumPanel.class, checkSumMenuItem.getText()));
260 fileMenu.add(checkSumMenuItem);
261
262 JMenuItem recoveryMenuItem = new JMenuItem(bundle.getString("file.password.recovery.title"));
263 recoveryMenuItem.addActionListener(new ChangeMenuToPanelListener(RecoveryPanel.class, recoveryMenuItem.getText()));
264 fileMenu.add(recoveryMenuItem);
265 }
266
267 private void createConvertMenu() {
268 JMenu convertMenu = new JMenu(bundle.getString("convert.title"));
269 menuBar.add(convertMenu);
270
271 JMenuItem timeConvertMenuItem = new JMenuItem(bundle.getString("convert.time.title"));
272 timeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(TimeConvertPanel.class, timeConvertMenuItem.getText()));
273 convertMenu.add(timeConvertMenuItem);
274
275 JMenuItem colorConvertMenuItem = new JMenuItem(bundle.getString("convert.color.title"));
276 colorConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(ColorConvertPanel.class, colorConvertMenuItem.getText()));
277 convertMenu.add(colorConvertMenuItem);
278
279 JMenuItem colorPickerMenuItem = new JMenuItem(bundle.getString("picker.color.title"));
280 colorPickerMenuItem.addActionListener(new ChangeMenuToPanelListener(ColorPickerPanel.class, colorPickerMenuItem.getText()));
281 convertMenu.add(colorPickerMenuItem);
282
283 JMenuItem baseConvertMenuItem = new JMenuItem(bundle.getString("convert.base.title"));
284 baseConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(BaseConvertPanel.class, baseConvertMenuItem.getText()));
285 convertMenu.add(baseConvertMenuItem);
286
287 JMenuItem unicodeConvertMenuItem = new JMenuItem(bundle.getString("convert.unicode.title"));
288 unicodeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(Zh2UnicodeConvertPanel.class, unicodeConvertMenuItem.getText()));
289 convertMenu.add(unicodeConvertMenuItem);
290
291 JMenuItem encodingRecoveryMenuItem = new JMenuItem(bundle.getString("garbled.text.recovery.title"));
292 encodingRecoveryMenuItem.addActionListener(new ChangeMenuToPanelListener(GarbledTextRecoveryPanel.class, encodingRecoveryMenuItem.getText()));
293 convertMenu.add(encodingRecoveryMenuItem);
294
295 JMenuItem relationShipConvertMenuItem = new JMenuItem(bundle.getString("convert.relationship.title"));
296 relationShipConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(RelationShipConvertPanel.class, relationShipConvertMenuItem.getText()));
297 convertMenu.add(relationShipConvertMenuItem);
298
299 JMenuItem unsupervisedProtobufConvertMenuItem = new JMenuItem(bundle.getString("convert.protobuf.unsupervised.title"));
300 unsupervisedProtobufConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(UnsupervisedProtobufConvertPanel.class, unsupervisedProtobufConvertMenuItem.getText()));
301 convertMenu.add(unsupervisedProtobufConvertMenuItem);
302
303 JMenuItem supervisedProtobufConvertMenuItem = new JMenuItem(bundle.getString("convert.protobuf.supervised.title"));
304 supervisedProtobufConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(SupervisedProtobufConvertPanel.class, supervisedProtobufConvertMenuItem.getText()));
305 convertMenu.add(supervisedProtobufConvertMenuItem);
306 }
307
308 private void createAndroidMenu() {
309 JMenu androidMenu = new JMenu(bundle.getString("android.title"));
310 menuBar.add(androidMenu);
311
312 JMenuItem i18nAddMenuItem = new JMenuItem(bundle.getString("android.i18n.add.title"));
313 i18nAddMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nAddPanel.class, i18nAddMenuItem.getText()));
314 androidMenu.add(i18nAddMenuItem);
315
316 JMenuItem i18nFindLongestMenuItem = new JMenuItem(bundle.getString("android.i18n.longest.title"));
317 i18nFindLongestMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nFindLongestPanel.class, i18nFindLongestMenuItem.getText()));
318 androidMenu.add(i18nFindLongestMenuItem);
319
320 JMenuItem i18nRemoveMenuItem = new JMenuItem(bundle.getString("android.i18n.remove.title"));
321 i18nRemoveMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nRemovePanel.class, i18nRemoveMenuItem.getText()));
322 androidMenu.add(i18nRemoveMenuItem);
323
324 JMenuItem screenShotMenuItem = new JMenuItem(bundle.getString("android.screenshot.title"));
325 screenShotMenuItem.addActionListener(new ChangeMenuToPanelListener(ScreenShotPanel.class, screenShotMenuItem.getText()));
326 screenShotMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
327 androidMenu.add(screenShotMenuItem);
328
329 JMenuItem monkeyMenuItem = new JMenuItem(bundle.getString("android.monkey.title"));
330 monkeyMenuItem.addActionListener(new ChangeMenuToPanelListener(MonkeyPanel.class, monkeyMenuItem.getText()));
331 androidMenu.add(monkeyMenuItem);
332
333 JMenuItem dumpsysMenuItem = new JMenuItem(bundle.getString("android.dumpsys.title"));
334 dumpsysMenuItem.addActionListener(new ChangeMenuToPanelListener(DumpsysPanel.class, dumpsysMenuItem.getText()));
335 androidMenu.add(dumpsysMenuItem);
336 }
337
338 private void createReverseMenu() {
339 JMenu reverseMenu = new JMenu(bundle.getString("reverse.title"));
340 reverseMenu.setMnemonic(KeyEvent.VK_R);
341 menuBar.add(reverseMenu);
342
343 JMenuItem pluginVersionMenuItem = new JMenuItem(bundle.getString("reverse.plugin.version.title"));
344 pluginVersionMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_PLUGIN_VERSION));
345 reverseMenu.add(pluginVersionMenuItem);
346
347 JMenuItem apktoolMenuItem = new JMenuItem(bundle.getString("reverse.apktool.title"), KeyEvent.VK_D);
348 apktoolMenuItem.addActionListener(new ChangeMenuToPanelListener(ApktoolPanel.class, apktoolMenuItem.getText()));
349 reverseMenu.add(apktoolMenuItem);
350
351 JMenuItem apkSignMenuItem = new JMenuItem(bundle.getString("reverse.apksigner.title"));
352 apkSignMenuItem.addActionListener(new ChangeMenuToPanelListener(ApkSignerPanel.class, apkSignMenuItem.getText()));
353 reverseMenu.add(apkSignMenuItem);
354
355 JMenuItem jDMenuItem = new JMenuItem(bundle.getString("reverse.jd.gui.title"));
356 jDMenuItem.addActionListener(new ChangeMenToPluginJdListener());
357 reverseMenu.add(jDMenuItem);
358
359 JMenuItem luytenMenuItem = new JMenuItem(bundle.getString("reverse.luyten.title"));
360 luytenMenuItem.addActionListener(new ChangeMenuToPluginLuytenListener());
361 reverseMenu.add(luytenMenuItem);
362
363 JMenuItem jdDuoMenuItem = new JMenuItem(bundle.getString("reverse.jd.duo.title"));
364 jdDuoMenuItem.addActionListener(new ChangeMenuToPluginJdDuoListener());
365 reverseMenu.add(jdDuoMenuItem);
366
367 JMenuItem jdaMenuItem = new JMenuItem(bundle.getString("reverse.jda.title"));
368 jdaMenuItem.addActionListener(new ChangeMenuToPluginJdaListener());
369 reverseMenu.add(jdaMenuItem);
370
371 JMenuItem jADXMenuItem = new JMenuItem(bundle.getString("reverse.jadx.title"));
372 jADXMenuItem.addActionListener(new ChangeMenuToPluginJadxListener());
373 reverseMenu.add(jADXMenuItem);
374
375 JMenuItem aXMLPrinter = new JMenuItem(bundle.getString("reverse.axmlprinter.title"));
376 aXMLPrinter.addActionListener(new ChangeMenuToPanelListener(AxmlPrinterPanel.class, aXMLPrinter.getText()));
377 reverseMenu.add(aXMLPrinter);
378 }
379
380 class ChangeMenuToPanelListener implements ChangeMenuListener {
381
382 Class<? extends EasyPanel> easyPanelClass;
383
384 EasyPanel panel = null;
385
386 String title;
387
388 public ChangeMenuToPanelListener(Class<? extends EasyPanel> easyPanelClass, String title) {
389 this.easyPanelClass = easyPanelClass;
390 this.title = title;
391 panel = createEasyPanel();
392 }
393
394 @Override
395 public boolean isNeedPreChangeMenu() {
396 return panel.isNeedPreChangeMenu();
397 }
398
399 @Override
400 public void onPreChangeMenu(IPreChangeMenuCallBack callBack) {
401 if (panel instanceof PluginPanel pluginPanel) {
402 pluginPanel.preparePlugin(new ChangeMenuPreparePluginController(pluginPanel.getPluginFilename(), pluginPanel.isPluginNeedUnzip(), pluginPanel.isPluginNeedUnzipToSeparateDir(), callBack));
403 }
404 }
405
406 @Override
407 public void onChangeMenu() {
408 UiStateKeeper.save(currentEasyPanel);
409 contentPane.removeAll();
410 contentPane.add(Box.createVerticalGlue());
411 panel.init();
412 panel.setBorder(BorderFactory.createTitledBorder(title));
413 contentPane.add(panel);
414 logger.info("Panel changed: " + panel.getClass().getSimpleName());
415 contentPane.add(Box.createVerticalGlue());
416 contentPane.revalidate();
417 contentPane.repaint();
418 refreshSizeAndLocation();
419 panel.afterPainted();
420 UiStateKeeper.restore(panel);
421 currentEasyPanel = panel;
422 }
423
424 private EasyPanel createEasyPanel() {
425 if (easyPanelClass == null) {
426 return new EasyPanel();
427 }
428 EasyPanel retEasyPanel = null;
429 try {
430 retEasyPanel = easyPanelClass.getDeclaredConstructor().newInstance();
431 } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
432 NoSuchMethodException e) {
433 logger.info("createEasyPanel failed: {}", e.getMessage());
434 }
435 return Objects.requireNonNullElseGet(retEasyPanel, EasyPanel::new);
436 }
437 }
438
439 @Override
440 protected void onWindowClosing(WindowEvent e) {
441 super.onWindowClosing(e);
442 UiStateKeeper.save(currentEasyPanel);
443 }
444
445 @Override
446 protected void onWindowIconified(WindowEvent e) {
447 super.onWindowIconified(e);
448 UiStateKeeper.save(currentEasyPanel);
449 }
450 }